package com.miot.restapi.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.util.LinkedList;
import java.util.List;

/**
 * @Author: zhangyanbin
 * @Date: 2019/1/4 17:50
 * @Version 1.0
 */
public class ControlUnitUtil {
    public static final String GET_METHOD = "GET";
    public static final String POST_METHOD = "POST";
    public static final String URI = "https://bridge.io.mi.com";
    private static final Long groupId = 1218L;
    private static final Long authUnitId = 17309038516633600L;
    private static final String privateKey = "MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCA96lBvNVypEGE7rNvwrQCXY2rbLcBXXfHALqVsVdsPmA";
    private static byte[] publicKey = Base64.decodeBase64(
            "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE27mFHWWKKZJjsuG5lKFBl6KEgnHLZU2T24A-ypDokpRL5BN9bQPWJGkMh9WZON8rd6kSVJSVuU24jiveQ22VAw");

    public ControlUnitUtil() {
    }

    protected static Logger logger = LoggerFactory.getLogger(ControlUnitUtil.class);


    public static List<NameValuePair> createParams(String method, String uri, String data) {
        String nonceStr = System.currentTimeMillis() + "";
        List<NameValuePair> params = new LinkedList<>();
        params.add(new BasicNameValuePair("_nonce", nonceStr));
        params.add(new BasicNameValuePair("_groupId", groupId + ""));
        params.add(new BasicNameValuePair("_authUnitId", authUnitId + ""));
        params.add(new BasicNameValuePair("_data", data));
        StringBuilder toSignTextBuilder = new StringBuilder();
        toSignTextBuilder.append(method).append("&").append(uri).append("&").append(data).append("&").append(nonceStr);
        String toSignText = toSignTextBuilder.toString();
        String sign = ECDSAUtil.signWithStr(toSignText.getBytes(), privateKey);
        params.add(new BasicNameValuePair("_signature", sign));
        return params;
    }

    /**
     * 解析小米返回的ControlUnitId
     *
     * @param miResult
     * @return
     */
    public static String getControlUnitId(String miResult) {
        if (StringUtils.isEmpty(miResult)) {
            return null;
        }
        String result = JSONObject.parseObject(miResult).getString("result");
        if ("ok".equals(result)) {
            if (JSONObject.parseObject(miResult).getJSONObject("data") != null) {
                return JSONObject.parseObject(miResult).getJSONObject("data").getString("controlUnitId");
            }
        }
        return null;
    }

    /**
     * 根据房间controlUnitId获取设备列表
     *
     * @param controlUnitId
     * @return
     */
    public static JSONArray getDeviceList(long controlUnitId) {
        try {
            String uri = "/bridge/controlunit/devices";
            JSONObject dataValueJson = new JSONObject();
            dataValueJson.put("controlUnitId", controlUnitId);
            dataValueJson.put("compact", false);
            List<NameValuePair> params = createParams(ControlUnitUtil.GET_METHOD, uri, dataValueJson.toString());
            String postResult = HttpUtils.sendGet(ControlUnitUtil.URI + uri, params, null);
            if (StringUtils.isEmpty(postResult)) {
                return new JSONArray();
            }
            String responseBody = JSONObject.parseObject(postResult).getJSONObject("data").getString("responseBody");
            byte[] bytes = Base64.decodeBase64(responseBody);
            String deviceList = new String(bytes);
            JSONArray devices = JSONObject.parseObject(deviceList).getJSONArray("devices");
            return devices;
        } catch (Exception e) {
            logger.error("接口getDeviceList获取设备列表错误信息是->{}", e.getMessage());
        }
        return new JSONArray();
    }


    /**
     * 根据设备类型查询设备属性
     *
     * @param type
     * @return
     */
    public static JSONObject getPropertiesByType(String type) {
        String url = "https://miot-spec.org/miot-spec-v2/instance?type=" + type;
        String properties = HttpUtils.sendGet(url);
        System.out.println(properties);
        return JSONObject.parseObject(properties);
    }

    /**
     * 设置设备属性接口
     *
     * @param properties
     * @param controlUnitId
     * @return
     */
    public static String setProperties(JSONArray properties, Long controlUnitId) {
        try {
            String uri = "/bridge/controlunit/properties";
            JSONObject finalJson = new JSONObject();
            finalJson.put("properties", properties);
            System.out.println(finalJson);
            String setPropertiesStr = Base64.encodeBase64URLSafeString(finalJson.toString().getBytes());
            JSONObject dataJSONObject = new JSONObject();
            dataJSONObject.put("controlUnitId", controlUnitId);
            dataJSONObject.put("properties", setPropertiesStr);
            List<NameValuePair> params = createParams(ControlUnitUtil.POST_METHOD, uri, dataJSONObject.toString());
            String postResult = HttpUtils.sendPost(ControlUnitUtil.URI + uri, params);
            String responseBody = JSONObject.parseObject(postResult).getJSONObject("data").getString("responseBody");
            byte[] bytes = Base64.decodeBase64(responseBody);
            String propertyResult = new String(bytes);
            return propertyResult;
        } catch (Exception e) {
            logger.error("setProperties方法设置设备属性接口->{}", e.getMessage());
        }
        return null;
    }

    /**
     * 小米解绑设备
     *
     * @param controlUnitId
     * @param realDid
     * @return
     */
    public static String unbound(Long controlUnitId, String realDid) {
        try{
            String uri = "/bridge/controlunit/unbind";
            JSONObject dataValueJson = new JSONObject();
            dataValueJson.put("controlUnitId", controlUnitId);
            dataValueJson.put("did", realDid);
            List<NameValuePair> params = ControlUnitUtil.createParams(ControlUnitUtil.POST_METHOD, uri, dataValueJson.toString());
            String postResult = HttpUtils.sendPost(ControlUnitUtil.URI + uri, params);
            return postResult;
        }catch (Exception e){
            logger.error("unbound方法小米解绑设备={}",e.getMessage());
        }
        return null;
    }
}
